home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ansi
/
hercules.zip
/
HERCBIOS.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-09-04
|
11KB
|
407 lines
;*******************************************************
;*
;* Main program file for HERCBIOS
;*
;* Dave Tutelman - 8/86
;*
;*------------------------------------------------------
;*
;* INT10 -- acts as pre-handler for video interrupts
;* (BIOS calls) for Hercules & SuperComputer
;* monochrome graphics board. Calls real BIOS
;* if not a Hercules special. Handled here are:
;*
;* Fn 0 Set mode (only 6 & 8)
;* and all functions, when in mode 6 or 8.
;* Actually, we've only implemented:
;* Fn 2 Set cursor position
;* Fn 3 Read cursor position
;* Fn 5 New display page
;* Fn 9 Write character with attribute
;* Fn 10 Write character
;* Fn 12 Write pixel
;* Fn 13 Read pixel
;* Fn 14 Teletypewriter-style character write
;* Fn 15 Get video status
;*
;* The only allowable modes for these boards are:
;* 6 IBM graphics (we handle it, but poor aspect ratio).
;* 7 Monochrome (with 2 pages)
;* 8 Hercules graphics mode.
;*
;**********************************************************
;
INCLUDE hercbios.h
extrn writechar:near,tty:near,scroll_up:near,scroll_down:near
extrn scr_start:word,scr_length:word,num_rows:byte
extrn wr_pixel:near
extrn end_herc:near
public exit_herc_bios,int10,vid_vector
public set_mode,set_curs,read_curs,new_page,status
;-----------------------------------------
page
;************************************************************
;*
;* Install the Hercules video handler
;*
;************************************************************
cseg segment public
assume cs:cseg,ds:cseg
ORG 100h
;
START:
;
push ax
push es
push ds
;
xor ax,ax ; zero the acc
mov es,ax ; ES points to zero (interrupt vector)
; Get ROM BIOS video entry point, and save in "rom_bios"
mov ax,es:[4*VIDI]
mov word ptr cs:rom_bios,ax
mov ax,es:[4*VIDI+2]
mov word ptr cs:rom_bios+2,ax
; Now plant the HERCBIOS entry point in interrupt vector
mov ax,offset int10 ; address of video handler to AX
mov es:[4*VIDI],ax ; and store it in interrupt vector 10H
mov ax,cs ; same for the segment of video handler
mov es:[4*VIDI+2],ax ; ...
;
; Leave the message that we're installed
mov ax,cs ; DS:DX pointing to message
mov ds,ax
mov dx,offset install_msg
mov ah,9 ; display-string function
int 21h
pop ds
pop es
pop ax
;
mov dx,offset end_herc ; set dx to end of this program
int 27H ; terminate, but stay resident
;
install_msg db "BIOS for Hercules-compatible Graphics - "
db "(DMT Aug 1986)",10,13,'$'
page
;************************************************************
;*
;* Beginning of video interrupt handler
;*
;************************************************************
;
;
int10 proc far
;
sti ; allow further interrupts
push ds ; save DS
push ax ; save AX
mov ax,bios_data ; bios data segment --> AX
mov ds,ax ; now put bios data segment in DS
assume ds:bios_data ; and tell assembler about it
; ; check current mode
mov ah,video_mode ; get current mode
cmp ah,herc_mode ; test for a graphics mode
je herc_bios
cmp ah,ibm_mode
je herc_bios
; ; setmode to a graphics mode?
pop ax ; restore AX
push ax ; ...but leave it on stack
cmp ax,0006 ; Fn = set to IBM hi-res mode?
je herc_bios
cmp ax,0008 ; Fn = set to Herc graphics mode?
je herc_bios
;
norm_bios: ; if we get here, just go to real BIOS
pop ax ; restore stack to pre-interrupt state
pop ds
db 0EAh ; opcode for FAR JUMP to rom_bios
rom_bios dd ? ; normal video bios address (in ROM)
;
herc_bios: ; jump table for special Hercules BIOS
;
pop ax ; restore ax
push bx ; save regs
push cx
push dx
push si
push di
push es
;
push ax
mov al,ah ; function # to AX
xor ah,ah
shl ax,1 ; *2 for word vector
mov si,ax ; put in SI to index into vector
pop ax ; restore old AX
cmp si,offset vid_vec_end-offset vid_vector
; function number within range?
jge exit_herc_bios ; function number out of range
add si,offset vid_vector
jmp word ptr cs:[si]
; jump to routine via vector
;
vid_vector: ; jump vector for hercules video routines
dw offset set_mode ; 0 = set mode
dw offset exit_herc_bios ; 1 = cursor type (NA)
dw offset set_curs ; 2 = set cursor position
dw offset read_curs ; 3 = read cursor position
dw offset exit_herc_bios ; 4 = light pen (NA)
dw offset new_page ; 5 = choose active page
dw offset scroll_up ; 6 = scroll up
dw offset scroll_down ; 7 = scroll down
dw offset exit_herc_bios ; 8 = read character (NA)
dw offset writechar ; 9 = write char & attribute
dw offset writechar ;10 = write character
dw offset exit_herc_bios ;11 = set color palette (NA)
dw offset wr_pixel ;12 = write pixel
dw offset wr_pixel ;13 = read pixel
dw offset tty ;14 = teletype write
dw offset status ;15 = return video state
vid_vec_end:
;
exit_herc_bios:
pop es ; restore regs
pop di
pop si
pop dx
pop cx
pop bx
pop ds
iret ; and return
page
;********************************************************************
;*
;* FUNCTION 0 - SET VIDEO MODE
;*
;* Only gets here to set a hi-res graphics mode
;* 6=IBM
;* 8=Hercules
;* [ AX destroyed ]
;*
;*******************************************************************
;
set_mode:
; ; is it a graphics mode?
cmp al,herc_mode ; set to hercules mode?
je g_mode
cmp al,ibm_mode ; set to IBM mode?
je g_mode
; Neither. Leave it to normal BIOS
pop es ; restore regs
pop di
pop si
pop dx
pop cx
pop bx
pop ds
jmp vid_bios ; and go to MPX-16 BIOS
;
g_mode: mov video_mode,al ; save video mode in BIOS data area
mov active_page,ah ; zero the active page in BIOS data
mov n_cols,90 ; 90 character columns in graphics mode
;
;* clear display area
mov ax,pixbase ; get starting address
mov es,ax ; page base to ES
mov cx,8000H ; word counter
mov di,0 ; start at beginning of display
cld ; direction "up"
xor ax,ax ; zero AX
rep stosw ; write zero to both pages
;
;* load the 6845 internal registers
;
; ; first set up the loop
push ds ; save DS
mov ax,cs ; get cseg into DS
mov ds,ax
assume ds:cseg
mov dx,vid_port ; 6845 index port address to DX
mov si,offset vid_parm_table
; table pointer to SI
mov cx,16 ; 16 parameters in table
xor ax,ax ; zero AX (AH will be index counter)
; ; now execute the loop
init_6845_loop:
mov al,ah ; index counter to AL
out dx,al ; output index to 6845
inc dx ; point DX to data reg
mov al,[si] ; get table entry
out dx,al ; output to 6845 data reg
dec dx ; point DX back to index reg
inc ah ; bump index counter
inc si ; bump table pointer
loop init_6845_loop
pop ds ; restore DS
assume ds:bios_data ; restore DS assumed
;
;* now set the 6845 control register
mov dx,vid_port+4 ; control port address
mov al,0AH ; graphics control byte
cmp active_page,0 ; get current page
je pg0_F0 ; skip if zero
or al,80H ; page 1 to control byte
pg0_F0: out dx,al ; and ship to 6845
mov chip_ctrl,al ; also save in bios data area
;
;* save cursor position (0,0) in bios data area
xor ax,ax ; zero AX
mov curs_pos,ax ; write zero to pg.0 cursor postion
mov curs_pos+2,ax ; write zero to pg.1 cursor postion
;
;* initialize scrolling parameters
;
cmp video_mode,herc_mode
je h_parm
mov cs:scr_start,180 ; IBM parameters
mov cs:scr_length,3690 ;
mov cs:num_rows,42 ;
jmp parm_done
h_parm: mov cs:scr_start,270 ; Herc parameters
mov cs:scr_length,3645 ;
mov cs:num_rows,28 ;
parm_done:
;
jmp exit_herc_bios
;
;* table of 6845 chip parameters
;
vid_parm_table db 53,45,46,7,91,2,87,87,2,3,62H,3,0,0,0,0
;vid_parm_table db 54,45,46,8,91,2,87,87,2,3,62H,3,0,0,0,0
;DMT's monitor
page
;********************************************************************
;*
;* FUNCTION 2 - SET CURSOR POSITION
;*
;* DX = new row (DH) and column (DL)
;* BH = display page number
;*
;********************************************************************
;
set_curs:
;
; * save in BIOS data area
mov bl,bh ; page # to bl
xor bh,bh ; zero bh (page # = BX)